﻿using System;
using Andromeda.Forge.DataSource.DB;
using Andromeda.Global.Business.DataObject;
using Andromeda.Global.Data;

namespace ForgeIt.Internal
{
    /// <summary>
    /// Represents a DatabaseConnectionString
    /// </summary>
    public class DataBaseConnectionModel : DataObjectModelBase
    {
        private readonly FODataSourceDBProject _project;


        /// <summary>
        /// Default constructor for SqlClient databases
        /// </summary>
        public DataBaseConnectionModel()
        {
            ProviderName = "System.Data.SqlClient";
        }

        /// <summary>
        /// Initializes the Model from an existing connectionstring in a Forge Db project
        /// </summary>
        /// <param name="project">The project to load the connection string from</param>
        public DataBaseConnectionModel(FODataSourceDBProject project)
            : this()
        {
            _project = project;
            DataSourceKey = project.Id;
            BaseNameSpace = project.BaseNameSpace;
            string[] keyValues = project.ConnectionString.Split(';');
            foreach (string keyValue in keyValues)
            {
                if (string.IsNullOrWhiteSpace(keyValue)) continue;
                string key = keyValue.Split('=')[0];
                string value = keyValue.Split('=')[1];
                if (key.ToLower().Equals("data source"))
                    DataSource = value;
                else if (key.ToLower().Equals("initial catalog"))
                    InitialCatalog = value;
                else if (key.ToLower().Equals("user id"))
                    UserId = value;
                else if (key.ToLower().Equals("password"))
                    UserPwd = value;
                else if (key.ToLower().Equals("persist security info"))
                {

                }
                else if (key.ToLower().Equals("multipleactiveresultsets"))
                {
                    EnableMARS = Convert.ToBoolean(value);
                }
                else if (key.ToLower().Equals("network library"))
                {
                    EnableTcpIp = true;
                }
                else
                {
                    AdditionalFields += key + '=' + value + ';';
                }
            }
        }

        /// <summary>
        /// Loads the model from a given connection string
        /// </summary>
        /// <param name="connectionString">The connection string to load from</param>
        public DataBaseConnectionModel(string connectionString)
            : this()
        {
            if (string.IsNullOrWhiteSpace(connectionString)) return;

            string[] keyValues = connectionString.Split(';');
            foreach (string keyValue in keyValues)
            {
                if (string.IsNullOrWhiteSpace(keyValue) || keyValue.IndexOf('=') < 0) continue;
                string key = keyValue.Split('=')[0];
                string value = keyValue.Split('=')[1];
                if (key.ToLower().Equals("data source"))
                    DataSource = value;
                else if (key.ToLower().Equals("initial catalog"))
                {
                    InitialCatalog = value;
                    DataSourceKey = value;
                }
                else if (key.ToLower().Equals("user id"))
                    UserId = value;
                else if (key.ToLower().Equals("password"))
                    UserPwd = value;
                else if (key.ToLower().Equals("persist security info"))
                {

                }
                else if (key.ToLower().Equals("multipleactiveresultsets"))
                {
                    EnableMARS = Convert.ToBoolean(value);
                }
                else if (key.ToLower().Equals("network library"))
                {
                    EnableTcpIp = true;
                }
                else
                {
                    AdditionalFields += key + '=' + value + ';';
                }
            }
        }

        /// <summary>
        /// Pointer to the parameter received project
        /// </summary>
        public FODataSourceDBProject Project
        {
            get { return _project; }
        }

        /// <summary>
        /// The key that uniquely identifies the Datasource (config key)
        /// </summary>
        public string DataSourceKey { get; set; }

        /// <summary>
        /// Non-standardized additional connection string fields
        /// </summary>
        public string AdditionalFields { get; set; }

        /// <summary>
        /// The database server name
        /// </summary>
        public string DataSource { get; set; }

        /// <summary>
        /// The initial database name
        /// </summary>
        public string InitialCatalog { get; set; }

        /// <summary>
        /// The user used to log on to the database
        /// </summary>
        public string UserId { get; set; }

        /// <summary>
        /// The password used to log on to the database
        /// </summary>
        public string UserPwd { get; set; }

        /// <summary>
        /// The base namespace used for this database code mapping structure
        /// </summary>
        public string BaseNameSpace { get; set; }

        /// <summary>
        /// The name of the database provider (e.g. - System.Data.SqlClient)
        /// </summary>
        public string ProviderName { get; protected set; }

        /// <summary>
        /// Enable Multiple Active Result Sets (will include "MultipleActiveResultSets=True" in the connection string)
        /// </summary>
        public bool EnableMARS { get; set; }

        /// <summary>
        /// Enable Multiple Active Result Sets (will include "Network Library=DBMSSOCN" in the connection string)
        /// </summary>
        public bool EnableTcpIp { get; set; }

        // TODO: Add support for windows based authentication

        /// <summary>
        /// The currently mapped connection string as derived from the currently set fields
        /// </summary>
        public string ConnectionString
        {
            get
            {
                return (string.IsNullOrEmpty(DataSource) ? "" : ";Data Source=" + DataSource) +
                       (string.IsNullOrEmpty(InitialCatalog) ? "" : ";Initial Catalog=" + InitialCatalog) +
                       ";Persist Security Info=True;" +
                       (string.IsNullOrEmpty(UserId) ? "" : ";User ID=" + UserId) +
                       (string.IsNullOrEmpty(UserPwd) ? "" : ";Password=" + UserPwd) +
                       (EnableMARS ? ";MultipleActiveResultSets=True;" : "") +
                       (EnableTcpIp ? ";Network Library=DBMSSOCN;" : "") +
                       ';' + AdditionalFields;
            }
        }

        /// <summary>
        /// Implemented for back compatibility
        /// </summary>
        public override DataConnectorCollection DataObjects
        {
            get { return new DataConnectorCollection(); }
        }
    }
}
